﻿using System;

namespace Samurai.Wakizashi.Workflow.Fluent
{
    public static class Extensions
    {
        public static StepBuildContext<T> Do<T>(this ISequentialWorkflow<T> sequentialWorkflow, Action action) where T : class, IWorkflowContext
        {
            if (sequentialWorkflow == null) throw new ArgumentNullException("sequentialWorkflow");
            if (action == null) throw new ArgumentNullException("action");

            return new StepBuildContext<T>
                       {
                           Workflow = sequentialWorkflow,
                           ParameterlessAction = action
                       };
        }

        public static StepBuildContext<T> If<T>(this StepBuildContext<T> stepBuildContext, Predicate<T> executionPredicate) where T : class, IWorkflowContext
        {
            if (stepBuildContext == null) throw new ArgumentNullException("stepBuildContext");
            if (executionPredicate == null) throw new ArgumentNullException("executionPredicate");

            stepBuildContext.ExecutionPredicate = executionPredicate;

            return stepBuildContext;
        }

        public static StepBuildContext<T> Named<T>(this StepBuildContext<T> stepBuildContext, string stepName) where T : class, IWorkflowContext
        {
            if (stepBuildContext == null) throw new ArgumentNullException("stepBuildContext");
            if (string.IsNullOrEmpty(stepName)) throw new ArgumentNullException("stepName");

            stepBuildContext.Name = stepName;

            return stepBuildContext;
        }

        public static StepBuildContext<T> OnThread<T>(this StepBuildContext<T> stepBuildContext, ThreadType threadType) where T : class, IWorkflowContext
        {
            if (stepBuildContext == null) throw new ArgumentNullException("stepBuildContext");

            stepBuildContext.Thread = threadType;

            return stepBuildContext;
        }

        public static void Done<T>(this StepBuildContext<T> stepBuildContext) where T : class, IWorkflowContext
        {
            if (stepBuildContext == null) throw new ArgumentNullException("stepBuildContext");
            if (stepBuildContext.ParameterlessAction == null) throw new InvalidOperationException("No action to register with the workflow.");

            stepBuildContext.Workflow.RegisterStep(stepBuildContext.ParameterlessAction, stepBuildContext.Thread, stepBuildContext.ExecutionPredicate, stepBuildContext.Name);
        }
    }
}
